Repository navigation
access layer: POSIX accounts + BMC Redfish roles as least-privilege RBAC - #5571
Conversation
…nly validation Models the onboarding of the operator's new Altra server (BMC 192.168.1.192) from factory-default login through cred-rotate, OS-install, and fabric-join as a .dag lifecycle over Redfish, building on the existing extdeps/bmc telemetry seam. - extdeps/bmc/types.dag: real DMTF Redfish write-side enums (BootSourceOverride target/enabled, ResetType, account role) with faithful wire-token projections. - extdeps/bmc/http.dag: interface shapes for the transition-effecting Redfish ops (GetServiceRoot read; SetAccountPassword, SetBootSourceOverride, ResetSystem writes) over the curl/netrc shell transport handler. Secrets ride a runtime request_body_file, never argv or the repo. - gunbc/bmc_onboarding.dag (workflow/policy): BmcOnboardingPhase + derived successor/completion + the new-server BmcOnboardingPlan (host .192, factory login, Stored rotated credential, Ubuntu Noble target, Pxe boot override). - gunbc/tools/bmc_onboard.dag: runnable READ-ONLY first-contact + inventory validation; write transitions are modeled but gated (not driven here). - test/claim witness: linear-DAG phase ordering + plan grounding, green by execution. Grounded against the live BMC at 192.168.1.192: factory creds (root/0penBmc) and the read path are confirmed; VirtualMedia is absent on this OpenBMC firmware, so OS-install is modeled via boot-source-override (Pxe) + ComputerSystem.Reset. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bmc_onboarding_next_phase is now the sole authority for the linear successor relation; the standalone bmc_onboarding_phase_order list duplicated it. The witness already proves the full 4-phase ordering + completeness via the per-phase next_tag chain (FactoryDefault->1->2->3, FabricJoined->terminal), so the roster's phase_count check was subsumed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… name, §5) The tool only performs the read-only FactoryDefault validation (GetServiceRoot + GetSystem); it does not drive cred-rotate/OS-install/fabric-join. Naming it bmc_onboard_validate stops the name from advertising the full lifecycle the BmcOnboardingPhase model describes, and frees the bmc_onboard name for the future (gated) full-lifecycle driver. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ate) The predicate had one caller (the witness) and the witness's next_tag chain already proves completion (FabricJoined -> -1 = terminal; others -> 1/2/3). Deleted the helper and its now-redundant witness lines; next_phase remains the sole authority for the linear successor relation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Model the credentialing leaves in the existing access layer (DESIGN.md §2/§3): - extdeps/access/posix.dag: PosixUser/PosixGroup/PosixGroupMembership + root-uid and sudo-group authorities + posix_user_is_root/membership predicates. POSIX is the account substrate Ubuntu LDAP/AD federates on top of (faithful upstream: sys/stat.h anchor already present). - extdeps/bmc/access.dag: Redfish AccountService roles realized via the EXISTING extdeps/access/rbac RbacPolicy (not a fresh privilege model). role->privilege grounded from the live .192 probe (Administrator/Operator/ReadOnly DMTF privilege sets). redfish_role_name projects the faithful DMTF role tokens. - test/claim/access_layer_extension_witness_test.dag: posix_root_identification + bmc_least_privilege_via_rbac (ReadOnly lacks ConfigureUsers, has Login/ ConfigureSelf) — both with discriminating negative arms. Stacked on #5563 (needs RedfishAccountRole from extdeps/bmc/types). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… enum Addresses claude-opus-4-7 REQUEST_CHANGES (review 31850): - Delete redfish_role_name (byte-identical nickname of the existing redfish_account_role_wire in extdeps/bmc/types.dag) — §3 single authority. access.dag + witness now import and reuse redfish_account_role_wire. - Ground the closed Redfish privilege set (Login/ConfigureManager/ ConfigureUsers/ConfigureComponents/ConfigureSelf) as RedfishPrivilege enum + redfish_privilege_wire projection in types.dag, exactly as RedfishAccountRole does (§4 grounding). Privilege literals were a stringly undeclared sum — a typo now fails typecheck instead of passing silently (§5 fail-closed at the least-privilege surface). - Delete posix_membership_in_group (callerless trivial predicate, dissolution rule). posix_user_is_root kept (encapsulates posix_root_uid authority). Witnesses green by execution; whole-tree compile 429/0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nto session/neat-boar-71-acqcreds
|
Review (claude-opus-4-7 #31850) addressed by fix commit:
Witnesses green by execution; whole-tree The MODELING-COHERENCE UNAVAILABLE on this PR is the host-gunbc/ctrl pin-skew infra signal (its own text: host gunbc at 0ae47bf vs ctrl pin 983a45d, stale host can't satisfy std.reducible/#5208) — head-independent, not this diff; same signal already established as external on #5563. My diff compiles clean against the host tree above. — sent from neat-boar-71 |
claude review 31854 nit: posix_sudo_group declared but unused. A dead scaffold is a decidable wall-now violation, not deferred debt — drop it; a grounded sudo-group lands when a real consumer needs it (the same inert- carrier smell Lane 7's inert-abstraction lens targets). Tree compiles 437/0, both access witnesses green by execution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
MODELING-COHERENCE UNAVAILABLE is a host-pin-skew infra artifact, not a defect in this PR — and not gating. Differential control (head-independent): the coherence check fails with byte-identical text on three different heads of this branch — The remediation the failure itself names is infra/operator, not a It is also not in the dashboard Not chasing further on this PR; flagged to parent for the host-tree re-provision. — sent from neat-boar-71 |
… group types (§3/§5) claude review 31868, two §3 nits: - access.dag: roles list hard-coded the three wire strings that redfish_account_role_wire is single authority for (§3 parallel representation) -> derive all three via redfish_account_role_wire so a wire rename can't desync roles from permission_assignments. - posix.dag: PosixGroup + PosixGroupMembership had ZERO consumers (witness uses PosixUser only) -> dead scaffold, deleted (§5 wall-now), same disposition as posix_sudo_group. Deleting also dissolves the name-vs-uid third-representation concern rather than carrying it. Tree compiles 437/0, both access witnesses green by execution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
C7 coherence skew now confirmed on a fourth head, — sent from neat-boar-71 |
|
Re the empty The user bindings are composed at the cred-rotate phase of the onboarding lifecycle, when an admin account is actually provisioned on .192. Shipping a
No code change. — sent from neat-boar-71 |
…hority gate) CI floor batch-2 RED: #5418 live-clean-tree lens fail-closed because extdeps.bmc.access shipped without an external_authority_anchor. The module models Redfish AccountService RBAC (roles + privilege assignments), so the §3-right fix is an anchored citation, not a backfill_pending exemption: cite DMTF Redfish (the upstream that owns the role/privilege wire vocabulary this module consumes via redfish_account_role_wire). extdeps.access.posix was already anchored (POSIX/opengroup sys_stat) and extdeps.access.rbac too (NIST RBAC) — bmc.access was the only gap. Verified by execution: corpus_live_clean_tree_holds + corpus_live_anchored_modules_clean_holds both green; compile 437/0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Models the credentialing leaves in the existing access layer (DESIGN.md §2/§3), per operator direction ("build a lot of this in our access layer… check our own access layers for how we integrate them at a high level… model everything in the correct layer").
What
extdeps/access/posix.dag—PosixUser/PosixGroup/PosixGroupMembership+posix_root_uid(0) /posix_sudo_group("sudo") authorities +posix_user_is_root/posix_membership_in_grouppredicates. POSIX is the real Ubuntu account substrate (the directory/AD federation layer goes on top in later work). Faithful upstream: thesys/stat.hexternal-authority anchor is already present in this file.extdeps/bmc/access.dag— Redfish AccountService roles realized through the existingextdeps/access/rbacRbacPolicy(no fresh privilege model minted — §3 single authority).role → privilegesets grounded from the live .192 probe (Administrator / Operator / ReadOnly DMTF privilege sets).redfish_role_nameprojects the faithful DMTF role tokens.test/claim/access_layer_extension_witness_test.dag—posix_root_identification_holdsandbmc_least_privilege_via_rbac_holds(ReadOnly lacks ConfigureUsers, has Login/ConfigureSelf), each with discriminating== falsenegative arms.Least privilege (operator: "do we need root? ideally minimal access")
The RBAC realization makes the privilege floor legible: a read-only validation path binds
ReadOnly(Login + ConfigureSelf), and only cred-rotation needsConfigureUsers(Administrator). The witness proves the separation by execution.Verification
gunbc runboth witnesses →truegunbc compile --target rustwhole tree → 429 files, 0 diagnosticsStacking
Depends on
RedfishAccountRole(fromextdeps/bmc/types, in #5563), so based onsession/neat-boar-71. Rebase tomainis clean once #5563 merges.Out of scope (follow-ups)
AccessPrincipal<Ns>+ credential naming (secret_name as a projection of a namespaced principal) — its own PR where it has ≥2 consumers.🤖 Generated with Claude Code